//
//  DiscoveryController.swift
//  首页发现界面
//
//  Created by smile on 2019/6/10.
//  Copyright © 2019 ixuea. All rights reserved.
//

import UIKit

//导入数据库框架
import RealmSwift

//导入发布订阅框架
import SwiftEventBus

//导入主题框架
import SwiftTheme

//导入日志框架
import CocoaLumberjack

class DiscoveryController: BaseMusicPlayerController {
    //日志Tag
    private static let TAG="DiscoveryController"
    
    /// 麦克风按钮
    @IBOutlet weak var btMicrophone: UIBarButtonItem!
    
    /// 列表控件
    @IBOutlet weak var collectionView: UICollectionView!
    
    /// 当前界面头部布局
    var header:DiscoveryHeaderView!
    
    /// 搜索按钮
    @IBOutlet weak var btSearch: UIButton!
    
    /// 当前界面列表数据
    var dataArray:[Any] = []
    
    /// 搜索控制器
    var searchViewController:PYSearchViewController!
    
    /// 热门搜索数据
    var popularSearchArray:[String] = []
    
    /// 异步任务
    var task:DispatchWorkItem?
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }
    
    
    override func initViews() {
        super.initViews()
        DDLogWarn("DiscoveryController initViews",tag: DiscoveryController.TAG)
        
//        navigationItem.title="发现"
        setTitle("发现")
        
        //设置搜索按钮圆角
        ViewUtil.showRadius(btSearch, 15)
        
        //去掉导航栏下面的阴影
        //如果大家需要可以留着
        //这个导航栏有层次感
        navigationController?.navigationBar.shadowImage = UIImage()
        
        //导航栏透明
        //这里设置导航透明后
        //就没有上面的灰色了
        navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
        
        //注册头部
        collectionView.register(UINib(nibName: DiscoveryHeaderView.NAME, bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: DiscoveryHeaderView.NAME)
        
        //创建一个标题Nib
        let titleNib=UINib(nibName: TitleCell.NAME, bundle: nil)
        
        //注册标题Cell
        collectionView.register(titleNib, forCellWithReuseIdentifier: TitleCell.NAME)
        
        //注册歌单Cell
        collectionView.register(UINib(nibName: SheetCell.NAME, bundle: nil), forCellWithReuseIdentifier: SheetCell.NAME)
        
        //注册单曲Cell
        collectionView.register(UINib(nibName: SongCell.NAME, bundle: nil), forCellWithReuseIdentifier: SongCell.NAME)
        
        //添加右侧按钮
        navigationItem.rightBarButtonItem = createPlayingBar()
        
        //主题配置
        
        //背景
        //白天显示白色
        //夜间显示深黑色
        view.theme_backgroundColor=[COLOR_STRING_WHITE,COLOR_STRING_DARK_BLACK]
        
        //导航栏字体颜色
        //白天为默认；也就是文字显示黑色
        //夜间为黑色；也就是文字显示白色
        navigationController!.navigationBar.theme_barStyle=ThemeBarStylePicker(styles: .default, .black)
        
        //麦克风图片
        btMicrophone.theme_tintColor=[COLOR_STRING_BLACK,COLOR_STRING_LIGHT_GREY]
        
        //搜索按钮
        btSearch.theme_backgroundColor=[COLOR_STRING_GROUP_TABLE_VIEW_BACKGROUND,COLOR_STRING_SEARCH_BACKGROUND]
    }
    
    override func initDatas() {
        super.initDatas()
        DDLogWarn("initDatas", level: .warning, tag: DiscoveryController.TAG)
        
        fetchBanner()
        
        fetchData()
        
        fetchPopularData()
        
//        //测试数据库使用
//        //创建一个对象
//        let person = Person()
//
//        //赋值
//        person.name = "ixuea"
//        person.age = 12
//        
//        //创建一个数据库
//        let realm = try! Realm()
//        
//        //保存数据
//        try! realm.write {
//            realm.add(person)
//        }
//
//        //查询所有人
//        let persons = realm.objects(Person.self)
//
//        //打印有多少个人
//        print("DiscoveryController initDatas person counts:\(persons.count)")
        
        //打印当前应用沙盒路径
        var path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
        
        //打印路径
        print("DiscoveryController initDatas document path:\(path)")
    }
    
    /// 获取热门搜索数据
    func fetchPopularData() {
        //添加测试数据
        //因为服务端没有实现热门搜索功能
        for i in 0..<10 {
            popularSearchArray.append("热门搜索\(i)")
        }
    }
    
    /// 加载首页数据
    func fetchData() {
        //添加一些测试数据
//        dataArray.append("这是标题1")
//        dataArray.append("这是标题2")
//        dataArray.append("这是标题3")
//        dataArray.append("这是标题4")
//        dataArray.append("这是标题5")
//        dataArray.append("这是标题6")
//        dataArray.append("这是标题7")
//        dataArray.append("这是标题8")
//        dataArray.append("这是标题9")
        
//        dataArray.append("推荐歌单")
//
//        for i in 1...10 {
//            let sheet = Sheet()
//            sheet.title = "这是歌单\(i)，标题可以很长长长长长长长长长长长长长长长"
//            dataArray.append(sheet)
//        }
//
//        dataArray.append("推荐单曲")
        
        //清除原来的数据
        dataArray.removeAll()
        
        //歌单数据
        Api.shared.sheets().subscribeOnSuccess { data in
            if let data = data?.data?.data {
                //添加标题
                self.dataArray.append("推荐歌单")
                
                //添加到歌单数据
                self.dataArray = self.dataArray+data
//                self.dataArray = self.dataArray+data
//                self.dataArray = self.dataArray+data
                
                //重新加载数据
//                self.collectionView.reloadData()
                
                //请求单曲列表
                Api.shared.songs().subscribeOnSuccess({ data in
                    if let data = data?.data?.data {
                        //添加标题
                        self.dataArray.append("推荐单曲")
                        
                        //添加单曲数据
                        self.dataArray=self.dataArray+data
                        
                        //重新加载数据
                        self.collectionView.reloadData()
                    }
                }).disposed(by: self.disposeBag)
            }
        }.disposed(by: disposeBag)
        
        //重新加载数据
//        collectionView.reloadData()
    }
    
    /// 获取轮播图数据
    func fetchBanner() {
        Api
            .shared
            .ads()
            .subscribeOnSuccess { data in
            
                //判断是否有广告
                if let data = data?.data?.data {
                    self.showBannerData(data)
                }
                
        }.disposed(by: disposeBag)
    }
    
    /// 显示轮播图数据
    ///
    /// - Parameter data: <#data description#>
    func showBannerData(_ data:[Ad]) {
        //将数据设置到头部控件中
        header.bindData(data)
    }
    
    override func initListeners() {
        super.initListeners()
        DDLogWarn("DiscoveryController initListeners")
        
        //添加一个通知监听
        
        //当用户点击了启动界面的广告
        //就会调用当前界面的onAdClick方法
        NotificationCenter.default.addObserver(self, selector: #selector(onAdClick(notification:)), name: NSNotification.Name(rawValue: AD_CLICK), object: nil)
    }
    
    /// 当用户点击了启动界面的广告后回调
    ///
    /// - Parameter notification: <#notification description#>
    @objc func onAdClick(notification:NSNotification) {
        let adUri=notification.userInfo!["adUri"] as! String
        
        print("DiscoveryController onAdClick:\(adUri)")
        
//        //使用WebController显示广告页面
//        let controller=navigationController!.storyboard!.instantiateViewController(withIdentifier: "Web") as! WebController
//
//        //设置参数
//        controller.title="活动详情"
//        controller.uri=adUri
//
//        //将控制器压入导航控制器
//        navigationController?.pushViewController(controller, animated: true)
        
        //使用重构后的方法打开
        WebController.start(navigationController!, "活动详情", adUri)
    }
    
    /// 获取列表类型
    ///
    /// - Parameter data: <#data description#>
    /// - Returns: <#return value description#>
    func typeForItemAtData(_ data:Any) -> CellType {
        if data is Sheet {
            //歌单
            return .sheet
        }else if  data is Song {
            //单曲
            return .song
        }
        
        //标题
        return .title
    }
    
    /// Cell类型
    /// 他是一个枚举
    /// 以后也可以重构
    /// 就是项目中所有的类型都用他
    ///
    /// - title: 标题
    /// - sheet: 歌单
    /// - song: 单曲
    enum CellType {
        case title
        
        case sheet
        
        case song
    }
    
    
    /// 左侧麦克风点击事件
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onMicroPhoneClick(_ sender: Any) {
        print("DiscoveryController onMicrophoneClick")
    }
    
    
    /// 搜索按钮点击
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onSearchClick(_ sender: Any) {
        print("DiscoveryController onSearchClick")
        
        //创建搜索控制器
        searchViewController=PYSearchViewController(hotSearches: popularSearchArray, searchBarPlaceholder: "请输入你想搜索的内容.")
        
        //设置代理
        searchViewController.delegate=self
        
        //设置搜索结果控制器显示模式
        //嵌入到当前界面
        searchViewController.searchResultShowMode = .embed
        
        //设置搜索结果显示控制器
        searchViewController.searchResultController=searchResultController
        
        //创建一个导航控制器
        let nav = UINavigationController(rootViewController: searchViewController)
        
        //显示控制器
        present(nav, animated: true, completion: nil)
        
    }
    
    /// 搜索结果显示控制器
    /// 懒加载
    lazy var searchResultController: UIViewController = {
        print("DiscoveryController searchResultController")
        
        //return self.storyboard!.instantiateViewController(withIdentifier: "SearchResult")
        
        return SearchResultController.init()
    }()
    
    
    /// 获取搜索建议
    ///
    /// - Parameter query: <#query description#>
    func fetchSuggestion(_ query:String) {
        Api.shared.searchSuggests(query).subscribeOnSuccess { (data) in
            if let data=data?.data{
                //处理搜索建议数据
                
                var suggestions:[String] = []
                
                //处理歌单搜索建议
                if data.sheets.count>0{
                    //获取字符串
                    suggestions=suggestions+data.sheets.map({ (searchTitle) -> String in
                        searchTitle.title
                    })
                }
                
                //处理用户搜索建议
                if data.users.count>0{
                    //获取字符串
                    suggestions=suggestions+data.users.map({ (searchTitle) -> String in
                        searchTitle.title
                    })
                }
                
                self.searchViewController.searchSuggestions=suggestions
            }else{
                //清空搜索建议
                self.defaultSuggestion()
            }
        }.disposed(by: disposeBag)
    }
    
    /// 默认搜索建议
    func defaultSuggestion() {
        searchViewController.searchSuggestions=[]
    }
    
    /// 尝试获取搜索建议
    /// 对搜索建议API进行限流
    /// 这部分代码可以封装
    ///
    /// - Parameter query: <#query description#>
    func tryFetchSuggestion(_ query:String) {
        cancelTask()
        
        //创建一个可取消的异步任务
        task=DispatchWorkItem{
            //这里就是异步任务执行回调
            self.fetchSuggestion(query)
        }
        
        //1000毫秒后获取建议
        DispatchQueue.main.asyncAfter(deadline: .now()+DispatchTimeInterval.milliseconds(1000), execute: task!)
    }
    
    /// 取消任务
    func cancelTask() {
        if let task = task {
            task.cancel()
            self.task=nil
        }
    }
    
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

    override func pageId() -> String? {
        return "Discovery"
    }
    
    
    /// 视图已经可见了
    /// - Parameter animated: <#animated description#>
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        //检查是否需要处理通知点击
        AppDelegate.shared.checkIfProcessNotificationClick()
    }
}

// MARK: - CollectionView数据源和代理
extension DiscoveryController: UICollectionViewDataSource,UICollectionViewDelegate{
    
    /// 返回有多个条目
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return dataArray.count
    }
    
    /// 返回当前位置的Cell
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - indexPath: <#indexPath description#>
    /// - Returns: <#return value description#>
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

//        //从CollectionView中获取一个Cell
//        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TitleCell.NAME, for: indexPath) as! TitleCell
//
//        //取出当前位置对应的数据
//        let data = dataArray[indexPath.row]
//
//        //绑定数据
//        cell.bindData(data as! String)
//
//        //把Cell返回回去
//        return cell
        
        //获取当前位置对应的数据
        let  data = dataArray[indexPath.row]
        
        //获取当前Cell的类型
        let type=typeForItemAtData(data)
        
        //判断当前对象的类型
        switch type {
        case .sheet:
            //歌单
            //从CollectionView中取出一个Cell
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SheetCell.NAME, for: indexPath) as! SheetCell
            
            //绑定数据
            cell.bindData(data as! Sheet)
            
            //返回Cell
            return cell
            
        case .song:
            //单曲
            //从CollectionView中取出一个Cell
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SongCell.NAME, for: indexPath) as! SongCell
            
            //绑定数据
            cell.bindData(data as! Song)
            
            //返回Cell
            return cell
            
        default:
            //标题
            //从CollectionView中取出一个Cell
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TitleCell.NAME, for: indexPath) as! TitleCell
            
            //绑定数据
            cell.bindData(data as! String)
            
            //返回Cell
            return cell
        }
    }
    
    /// 返回CollectionView的Header
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - kind: <#kind description#>
    ///   - indexPath: <#indexPath description#>
    /// - Returns: <#return value description#>
    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        //将header中的内容都封装到单独的View中
        //好处是当前界面简洁一些
        //但坏处是头部的点击事件，需要通过一些方法
        //才能回调到当前界面
        header = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: DiscoveryHeaderView.NAME, for: indexPath) as! DiscoveryHeaderView
        
        //设置轮播图点击的回调方法
        //类似于OC中的block
        header.onBannerClick = {
            data in
            print("DiscoveryController onBannerClick:\(data.title)")
            
            //使用Web控制器显示广告界面
            WebController.start(self.navigationController!, data.title, data.uri)
        }
        
        return header
    }
    
    /// 返回Header大小
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - collectionViewLayout: <#collectionViewLayout description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        //获取到当前CollectionView的宽度
        let collectionViewWidth=collectionView.frame.width
        
        return CGSize(width: collectionViewWidth, height: SIZE_DISCOVERY_HEADER_HEIGHT)
    }
    
    /// Item点击事件
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - indexPath: <#indexPath description#>
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        //取出当前位置的数据
        let data = dataArray[indexPath.row]
        
        //获取当前对象的类型
        let type = typeForItemAtData(data)
        
        print("DiscoveryController didSelectItemAt:\(indexPath.row)")
        
        switch type {
        case .sheet:
            //跳转到歌单详情
            let data = data as! Sheet
            SheetDetailController.start(navigationController!, data.id)
        case .song:
            //跳转到播放界面
            let data = data as! Song
            
            //设置到播放列表
            playListManager.setPlayList([data])
            
            //播放当前音乐
            playListManager.play(data)
            
            //进入播放界面
            pushMusicPlayerController()
            
        default:
            break
        }
    }
}

// MARK: - UICollectionViewDelegateFlowLayout代理相关的方法
// 返回CollectionView相关的间隔
extension DiscoveryController: UICollectionViewDelegateFlowLayout {
    
    /// 返回CollectionView里面的Cell到CollectionView的间距
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - collectionViewLayout: <#collectionViewLayout description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
//        return UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50)
        return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    }
    
    /// 返回每个Cell的行间距
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - collectionViewLayout: <#collectionViewLayout description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return SIZE_LARGE_DIVIDER
    }
    
    /// 返回每个Cell的列间距
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - collectionViewLayout: <#collectionViewLayout description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return SIZE_LARGE_DIVIDER
    }
    
    /// 返回当前Cell的大小
    ///
    /// - Parameters:
    ///   - collectionView: <#collectionView description#>
    ///   - collectionViewLayout: <#collectionViewLayout description#>
    ///   - indexPath: <#indexPath description#>
    /// - Returns: <#return value description#>
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        //获取CollectionView的宽
        let collectionViewWidth=collectionView.frame.width
        
        //计算每列的宽度
//        let width=collectionViewWidth/3
        
        //10：是每列的间距
        //*2：是因为显示三列
        //其实只有两个边距
//        let width=(collectionViewWidth-10*2)/3
//
//        //返回当前Cell宽高
//        return CGSize(width: width, height: width)
        
//        return CGSize(width: collectionViewWidth, height: 40)
        
        //获取当前位置对应的数据
        let data=dataArray[indexPath.row]
        
        //最终的宽高
        var width:CGFloat!
        var height:CGFloat!
        
        //获取当前对象的类型
        let type=typeForItemAtData(data)
        
        switch type {
        case .sheet:
            //歌单
            //3列
            width=(collectionViewWidth-SIZE_LARGE_DIVIDER*2)/3
            
            //计算高度
            height=width+SIZE_LARGE_DIVIDER+SIZE_TITLE_HEIGHT+SIZE_LARGE_DIVIDER
            
        case .song:
            //单曲
            width=collectionViewWidth
            
            //5+110(图片高度)+5
            height=110
        default:
            //标题
            width=collectionViewWidth
            height=SIZE_TITLE_HEIGHT
        }
        
        return CGSize(width: width, height: height)
    }
}

// MARK: - 搜索框架代理
extension DiscoveryController:PYSearchViewControllerDelegate{
    
    /// 开始搜索时调用
    /// 点击搜索
    /// 点击历史
    /// 点击搜索提示都会调用
    ///
    /// - Parameters:
    ///   - searchViewController: <#searchViewController description#>
    ///   - searchBar: <#searchBar description#>
    ///   - searchText: <#searchText description#>
    func searchViewController(_ searchViewController: PYSearchViewController!, didSearchWith searchBar: UISearchBar!, searchText: String!) {
        print("DiscoveryController didSearchWith:\(searchText)")
        
        //发送搜索通知
        SwiftEventBus.post(ON_SEARCH_CLICK, sender: searchText)
    }
    
    /// 搜索输入框内容改变了调用
    ///
    /// - Parameters:
    ///   - searchViewController: <#searchViewController description#>
    ///   - searchBar: <#searchBar description#>
    ///   - searchText: <#searchText description#>
    func searchViewController(_ searchViewController: PYSearchViewController!, searchTextDidChange searchBar: UISearchBar!, searchText: String!) {
        print("DiscoveryController searchTextDidChange:\(searchText)")
        
        if searchText.length>0 {
            //获取搜索建议
            tryFetchSuggestion(searchText)
        } else {
            //清空搜索建议
            self.defaultSuggestion()
        }
    }
}
